package com.egdigital.allzic.ui.fragment;

import java.text.Normalizer;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.text.SpannableStringBuilder;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.Spinner;
import android.widget.TextView;

import com.android.volley.VolleyError;
import com.daimajia.androidanimations.library.Techniques;
import com.daimajia.androidanimations.library.YoYo;
import com.egdigital.allzic.R;
import com.egdigital.allzic.data.json.JsonCallBack;
import com.egdigital.allzic.data.json.JsonParserCity;
import com.egdigital.allzic.data.json.JsonParserCountry;
import com.egdigital.allzic.data.json.JsonParserStation;
import com.egdigital.allzic.data.json.VolleyManager;
import com.egdigital.allzic.data.object.Country;
import com.egdigital.allzic.data.object.Station;
import com.egdigital.allzic.service.DownloadState;
import com.egdigital.allzic.ui.activity.ActivityMain;
import com.egdigital.allzic.ui.adapter.AdapterCountry;
import com.egdigital.allzic.ui.adapter.AdapterListRadio;
import com.egdigital.allzic.utils.NetworkManager;
import com.egdigital.allzic.utils.Utils;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.Animator.AnimatorListener;

public class FragmentCategoryInternational extends BaseMainFragment implements OnItemClickListener, OnClickListener {

	private static final String		TAG					= FragmentCategoryInternational.class.getSimpleName();				// log
	private static final String		URL_BY_CITY			= "http://www.allzicradio.com/json/get_radios_by_city/%s/%s/%d";
	private static final String		URL_CITIES			= "http://www.allzicradio.com/json/get_cities/%s/0/10000";
	private List<String>			mListCity;
	private List<Station>			mListStation;
	private JsonParserCountry		mJsonParserCountry;
	private JsonParserCity			mJsonParserCity;
	private JsonParserStation		mJsonParserStation;
	private Country					mCurrentCountry;
	private String					mCurrentCity, mTitleString;
	private boolean					mCountrySelected	= false;
	private int						mSelectedItem		= -1;
	private int						mCurrentPage		= 0;
	//
	private View					mLine;
	private AdapterListRadio		mAdapterListRadio;
	private AdapterCountry			mAdapterCountry;
	private ArrayAdapter<String>	mSpinnerAdapter;
	private RelativeLayout			mTitleBarLayout, mSpinnerLayout;
	private ListView				mListView;
	private ProgressBar				mLoadingMoreStation;
	private Spinner					mSpinner;
	private TextView				mTitle;
	private ImageView				mImageArrowBack;
	private ImageButton				mcloseButton;
	// network ui
	protected ActivityMain			mParent;
	protected View					mView;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		mView = inflater.inflate(R.layout.fragment_category_international, container, false);
		mLoadingView = (RelativeLayout) mView.findViewById(R.id.fragment_category_international_loading);
		mReloadView = (LinearLayout) mView.findViewById(R.id.fragment_category_international_reload);
		mNoResultView = (TextView) mView.findViewById(R.id.fragment_category_international_noresult);
		//
		mLine = (View) mView.findViewById(R.id.shadow_spinner);
		mListView = (ListView) mView.findViewById(R.id.fragment_category_international_list);
		mTitle = (TextView) mView.findViewById(R.id.fragment_category_international_title);
		mcloseButton = (ImageButton) mView.findViewById(R.id.fragment_category_international_close);
		mSpinner = (Spinner) mView.findViewById(R.id.fragment_category_international_spinner);
		mLoadingMoreStation = (ProgressBar) mView.findViewById(R.id.fragment_category_international_listprogressbar);
		mTitleBarLayout = (RelativeLayout) mView.findViewById(R.id.fragment_category_international_title_layout);
		mSpinnerLayout = (RelativeLayout) mView.findViewById(R.id.fragment_category_international_spinner_layout);
		mImageArrowBack = (ImageView) mView.findViewById(R.id.fragment_category_international_back);
		return mView;
	}

	@Override
	public void onViewCreated(View view, Bundle savedInstanceState) {
		mView.setOnTouchListener(new View.OnTouchListener() {

			public boolean onTouch(View v, MotionEvent event) {
				return true;
			}
		});
		// title
		Bundle bundle = this.getArguments();
		mTitleString = bundle.getString("title");
		mListView.setOnItemClickListener(this);
		mcloseButton.setOnClickListener(this);
		mTitleBarLayout.setOnClickListener(this);
		mReloadView.setOnClickListener(this);
		setBackButton(false, mTitleString);
		super.onViewCreated(view, savedInstanceState);
	}

	@Override
	public void onResume() {
		super.onResume();
		// analytics
		analyticsSendEvent("International");
		if (mParent != null) {
			VolleyManager.init(mParent);
		}
		setCountryCallback();
		setCityCallback();
		setStationCallback();
	}

	public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
		if (mCountrySelected == false) {
			mCountrySelected = true;
			mCurrentCountry = mParent.getmListCountry().get(position);
			loadCityDataFromCountry(mCurrentCountry.getId(), mCurrentPage);
			setBackButton(true, mCurrentCountry.getTitle());
		} else {
			if (mListStation != null && position < mListStation.size()) {
				Station station = mListStation.get(position);
				mParent.prepareToPlay(station);
				mParent.showPlayerBanner();
				mParent.updatePlayerBanner();
			}
		}
	}

	public void onClick(View view) {
		switch (view.getId()) {
			case R.id.fragment_category_international_reload:
				if (mCountrySelected) {
					loadCityDataFromCountry(mCurrentCountry.getTitle(), mCurrentPage);
				} else {
					loadCountryData();
				}
				break;
			case R.id.fragment_category_international_close:
				mParent.removeFragment();
				break;
			case R.id.fragment_category_international_title_layout:
				if (!mDownloadState.equals(DownloadState.LOADING)) {
					mCountrySelected = false;
					mSelectedItem = -1;
					setSpinner(false);
					setLoaded(mListView);
					if (mListStation != null) {
						mListStation.clear();
					}
					if (mListCity != null) {
						mListCity.clear();
					}
					if (mSpinnerAdapter != null) {
						mSpinnerAdapter.notifyDataSetChanged();
					}
					setBackButton(false, mTitleString);
					updateAdapterCountry(mParent.getmListCountry());
				}
				break;
		}
	}

	/**
	 * fragment life cycle
	 */
	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		mParent = (ActivityMain) activity;
	}

	@Override
	public void onDetach() {
		super.onDetach();
		mParent.mExplorerSelected = false;
		mParent = null;
		if (mJsonParserCountry != null) {
			mJsonParserCountry.stopRequestQueue();
		}
		if (mJsonParserCity != null) {
			mJsonParserCity.stopRequestQueue();
		}
		if (mJsonParserStation != null) {
			mJsonParserStation.stopRequestQueue();
		}
	}

	/**
	 * loading data
	 */
	private void loadCountryData() {
		if (NetworkManager.isConnected(mParent.getApplicationContext())) {
			if (mParent.getmListCountry() != null && !mParent.getmListCountry().isEmpty()) {
				updateAdapterCountry(mParent.getmListCountry());
			} else {
				mJsonParserCountry.extractJsonObjectData(getString(R.string.url_around_country_all));
			}
		} else {
			setReload(mListView);
		}
	}

	private void loadStationFromCountry(String country) {
		if (NetworkManager.isConnected(mParent.getApplicationContext())) {
			String url = getString(R.string.url_around_country) + country;
			mJsonParserStation.extractJsonObjectData(url);
		} else {
			Utils.customToast(new SpannableStringBuilder(getString(R.string.no_network)), mParent.getApplicationContext(), true);
		}
	}

	private void loadCityDataFromCountry(String country, int page) {
		if (NetworkManager.isConnected(mParent.getApplicationContext())) {
			String url = String.format(URL_CITIES, country);
			mJsonParserCity.extractJsonObjectData(url);
		} else {
			Utils.customToast(new SpannableStringBuilder(getString(R.string.no_network)), mParent.getApplicationContext(), true);
		}
	}

	private void loadStationDataFromCity(String country, String city, int page) {
		if (NetworkManager.isConnected(mParent.getApplicationContext())) {
			String url = String.format(URL_BY_CITY, country, city, page);
			url = Normalizer.normalize(url, Normalizer.Form.NFD);
			url = url.replaceAll("[^\\p{ASCII}]", "");
			mJsonParserStation.extractJsonObjectData(url);
		} else {
			Utils.customToast(new SpannableStringBuilder(getString(R.string.no_network)), mParent.getApplicationContext(), true);
		}
	}

	/**
	 * animation
	 */
	@Override
	public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
		Animation animation = super.onCreateAnimation(transit, enter, nextAnim);
		// HW layer support only exists on API 11+
		if (animation == null && nextAnim != 0) {
			animation = AnimationUtils.loadAnimation(getActivity(), nextAnim);
		}
		if (animation != null) {
			animation.setAnimationListener(new AnimationListener() {

				public void onAnimationEnd(Animation animation) {
					getView().post(new Runnable() {

						@Override
						public void run() {
							try {
								loadCountryData();
							} catch (Exception e) {
							}
						}
					});
				}

				@Override
				public void onAnimationRepeat(Animation animation) {
				}

				@Override
				public void onAnimationStart(Animation animation) {
				}
			});
		}
		return animation;
	}

	/**
	 * json callback
	 */
	private void setCountryCallback() {
		if (mJsonParserCountry == null) {
			mJsonParserCountry = JsonParserCountry.getInstance();
			mJsonParserCountry.initAndStartRequestQueue();
		}
		mJsonParserCountry.setJsonCallBack(new JsonCallBack() {

			@Override
			public void downloadStarted() {
				setLoading(mListView);
			}

			@Override
			public void downloadPercent(int percent) {
				// do nothing
			}

			@Override
			public <T> void downloadCompleted(List<T> list) {
				if (mParent == null || list == null) {
					return;
				}
				if (!list.isEmpty()) {
					setLoaded(mListView);
					// sort
					Collections.sort(list, new Comparator<Object>() {

						public int compare(Object o1, Object o2) {
							Country p1 = (Country) o1;
							Country p2 = (Country) o2;
							return p1.getTitle().compareToIgnoreCase(p2.getTitle());
						}
					});
					mParent.setmListCountry((List<Country>) list);
					updateAdapterCountry((List<Country>) list);
				} else {
					setNoResult(mListView);
				}
			}

			@Override
			public void downloadEndedWithError(VolleyError error) {
				setReload(mListView);
			}
		});
	}

	private void setCityCallback() {
		if (mJsonParserCity == null) {
			mJsonParserCity = JsonParserCity.getInstance();
			mJsonParserCity.initAndStartRequestQueue();
		}
		mJsonParserCity.setJsonCallBack(new JsonCallBack() {

			@Override
			public void downloadStarted() {
				setLoading(mListView);
			}

			@Override
			public void downloadPercent(int percent) {
				// do nothing
			}

			@Override
			public void downloadEndedWithError(VolleyError error) {
				setReload(mListView);
			}

			@Override
			public <T> void downloadCompleted(List<T> list) {
				if (mParent == null || list == null) {
					return;
				}
				if (!list.isEmpty()) {
					setLoaded(mListView);
					// sort
					Collections.sort(list, new Comparator<Object>() {

						public int compare(Object o1, Object o2) {
							String p1 = (String) o1;
							String p2 = (String) o2;
							return p1.compareToIgnoreCase(p2);
						}
					});
					mListCity = (List<String>) list;
					mListCity.add(0, getString(R.string.fragment_category_international_all) + " (" + mListCity.size() + ")");
					//
					updateAdapterSpinner(mListCity);
					setLoaded(mListView);
				} else {
					setNoResult(mListView);
				}
			}
		});
	}

	private void setStationCallback() {
		if (mJsonParserStation == null) {
			mJsonParserStation = new JsonParserStation();
			mJsonParserStation.initAndStartRequestQueue();
		}
		mJsonParserStation.setJsonCallBack(new JsonCallBack() {

			@Override
			public void downloadStarted() {
				setLoading(mListView);
			}

			@Override
			public void downloadPercent(int percent) {
				// do nothing
			}

			@Override
			public void downloadEndedWithError(VolleyError error) {
				setReload(mListView);
			}

			@Override
			public <T> void downloadCompleted(List<T> list) {
				if (mParent == null || list == null) {
					return;
				}
				if (!list.isEmpty()) {
					setLoaded(mListView);
					// sort
					Collections.sort(list, new Comparator<Object>() {

						public int compare(Object o1, Object o2) {
							Station p1 = (Station) o1;
							Station p2 = (Station) o2;
							return p1.getmTitle().compareToIgnoreCase(p2.getmTitle());
						}
					});
					mListStation = (List<Station>) list;
					//
					updateAdapterStation(mListStation);
				} else {
					setNoResult(mListView);
				}
			}
		});
	}

	/**
	 * adapters
	 */
	private void updateAdapterCountry(List<Country> list) {
		if (list == null) {
			return;
		}
		mAdapterCountry = null;
		mAdapterCountry = new AdapterCountry(mParent.getApplicationContext(), list);
		mListView.setVisibility(View.VISIBLE);
		mListView.setAdapter(mAdapterCountry);
		mListView.setOnItemClickListener(this);
	}

	private void updateAdapterStation(List<Station> list) {
		if (list == null) {
			return;
		}
		mAdapterListRadio = null;
		mAdapterListRadio = new AdapterListRadio(mParent.getApplicationContext(), list, R.layout.cell_list_radio);
		mListView.setVisibility(View.VISIBLE);
		mListView.setAdapter(mAdapterListRadio);
		mListView.setOnItemClickListener(this);
	}

	private void updateAdapterSpinner(List<String> list) {
		mSpinnerAdapter = null;
		mSpinnerAdapter = new ArrayAdapter<String>(mParent.getApplicationContext(), android.R.layout.simple_spinner_item, list);
		mSpinnerAdapter.setDropDownViewResource(R.layout.view_drop_down);
		setSpinner(true);
		mSpinner.setSelection(-1);
		mSpinner.setAdapter(mSpinnerAdapter);
		mSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
				mCurrentPage = 0;
				if (position > 0 && position < mListCity.size() && mSelectedItem != -1) {
					mCurrentCity = mListCity.get(position);
					loadStationDataFromCity(mCurrentCountry.getId(), mCurrentCity, mCurrentPage);
				} else {
					loadStationFromCountry(mCurrentCountry.getId());
				}
				mSelectedItem = position;
			}

			@Override
			public void onNothingSelected(AdapterView<?> adapterView) {
				// do nothing
			}
		});
	}

	private void setSpinner(boolean visible) {
		if (visible) {
			mSpinner.setSelection(mSelectedItem);
			mSpinner.setVisibility(View.VISIBLE);
			mSpinnerLayout.setVisibility(View.VISIBLE);
			mLine.setVisibility(View.VISIBLE);
		} else {
			mSpinner.setVisibility(View.GONE);
			mSpinnerLayout.setVisibility(View.GONE);
			mLine.setVisibility(View.GONE);
		}
	}

	private void setBackButton(boolean visible, final String title) {
		if (visible) {
			YoYo.with(Techniques.FadeOut).duration(500).withListener(new AnimatorListener() {

				@Override
				public void onAnimationStart(Animator arg0) {
				}

				@Override
				public void onAnimationRepeat(Animator arg0) {
				}

				@Override
				public void onAnimationEnd(Animator arg0) {
					mImageArrowBack.setVisibility(View.VISIBLE);
					mTitle.setText(title);
					YoYo.with(Techniques.FadeIn).duration(500).playOn(mTitle);
				}

				@Override
				public void onAnimationCancel(Animator arg0) {
				}
			}).playOn(mTitle);
		} else {
			YoYo.with(Techniques.FadeOut).duration(500).withListener(new AnimatorListener() {

				@Override
				public void onAnimationStart(Animator arg0) {
				}

				@Override
				public void onAnimationRepeat(Animator arg0) {
				}

				@Override
				public void onAnimationEnd(Animator arg0) {
					mImageArrowBack.setVisibility(View.GONE);
					mTitle.setText(title);
					YoYo.with(Techniques.FadeIn).duration(500).playOn(mTitle);
				}

				@Override
				public void onAnimationCancel(Animator arg0) {
				}
			}).playOn(mTitle);
		}
	}
}
